package com.xe.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class XEReflex {

	  public  Object executeSetter(Object o, String attribute,Object value) {
	        String method = "set" + attribute.substring(0, 1).toUpperCase()
	                + attribute.substring(1);
	        	Object[] params = new Object[1];
	        	Class[] types = new Class[1];
	        	params[0]=value;
	        	if (value!=null){
	        		types[0]=value.getClass();
	        	}
	        	else{
	        		try {
						types[0]= o.getClass().getDeclaredField(attribute).getType();
					} catch (NoSuchFieldException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (SecurityException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
	        		
	        		}
	            return executeMethod(o, method, params, types);
	    }
	
	  public  Object executeGetter(Object o, String attribute) {
		  	
		    Field f;
		    String prefix="get";

			try {
				f = o.getClass().getDeclaredField(attribute);
			    if (f.getType().equals(Boolean.class) || f.getType().equals(boolean.class))
			    {
			    	//prefix="is";
			    	prefix="get";//
			    }
			} catch (NoSuchFieldException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		  
	        String method = prefix + attribute.substring(0, 1).toUpperCase()
	                + attribute.substring(1);
	        if (attribute.contains(".")) {
	            String[] s1 = attribute.replace(".", ":").split(":");
	            Object o1 = o;
	            for (String s : s1) {
	                if (o1 == null)
	                    return null;
	                o1 = executeGetter(o1, s);
	            }
	            return o1;
	        } else
	            return executeMethod(o, method, null, null);
	    }
	    
	    
	    public Object executeMethod(Object o, String method, Object[] params,
	            Class[] paramsTypes) {
	        System.out.println("+++executeMethod" + method);
	        Class c = o.getClass();
	        Method m;

	        try {

	            Class[] parTypes = null;

	            if (params != null && params.length > 0) {
	                parTypes = new Class[params.length];
	                for (int i = 0; i < params.length; i++) {
	                    parTypes[i] = paramsTypes[i];
	                }
	                System.out.println("JC:executeMethod params" + params);
	                m = c.getMethod(method, parTypes);
	                return m.invoke(o, params);
	            } else {
	                m = c.getMethod(method);
	                return m.invoke(o);
	            }
	        } catch (Exception e) {
	        	System.out.println("Error metodo no encontrado:" + o.getClass() + " " + method);
	            e.printStackTrace();
	        }
	        return null;
	    }

	    private void describe(Object object) {
	        Class c = object.getClass();
	        System.out.println("Describe Object" + c.getClass().getName());

	        System.out.println("Class:");
	        System.out.println(c.getName());

	        System.out
	                .println("---------------------DECLARED ANNOTATION:--------------------------------");
	        for (Annotation a : c.getDeclaredAnnotations()) {
	            System.out.println("----------Anotation:"
	                    + a.annotationType().getName());

	        }

	        /* Fields */
	        System.out
	                .println("---------------------Fields:----------------------------------------");
	        for (Field field : c.getDeclaredFields()) {
	            System.out.println("Fields:" + field.getType().getName() + " "
	                    + field.getName());
	            System.out.println("Fields Annotations... ");
	            for (Annotation a : field.getDeclaredAnnotations()) {
	                System.out.println("----------Anotation:"
	                        + a.annotationType().getName());
	            }
	        }

	        /* Methods */
	        System.out.println("Methods:");
	        for (Method method : c.getMethods()) {
	            System.out.println("Metodos:" + method.getReturnType().getName()
	                    + " " + method.getName() + "(");
	            for (Class p : method.getParameterTypes()) {
	                System.out.print(p.getName());
	            }
	            System.out.println(")");
	        }

	    }
	
	
	
}
